/**
 * A rope joint enforces a maximum distance between two points
 * on two bodies. It has no other effect.
 * Warning: if you attempt to change the maximum length during
 * the simulation you will get some non-physical behavior.
 * A model that would allow you to dynamically modify the length
 * would have some sponginess, so I chose not to implement it
 * that way. See b2DistanceJoint if you want to dynamically
 * control length.
**/
public class b2RopeJoint extends b2Joint {
	public b2RopeJoint(int addr) {
		super(addr);
	}

	@Override
	public void release() {
		if ( address != 0 ) {
			super.release();
		}
	}

	/**remember to call release() on the returned object*/
	public b2Vec2 GetAnchorA() {
		return new b2Vec2(jniGetAnchorA(address));
	}

	/**remember to call release() on the returned object*/
	public b2Vec2 GetAnchorB() {
		return new b2Vec2(jniGetAnchorB(address));
	}

	/// Get the reaction force given the inverse time step.
	/// Unit is N.
	public b2Vec2 GetReactionForce(float inv_dt) {
		return new b2Vec2(jniGetReactionForce(address));
	}

	/// Get the reaction torque due to the joint limit given the inverse time step.
	/// Unit is N*m.
	public float GetReactionTorque(float inv_dt) {
		return jniGetReactionTorque(address, inv_dt);
	}

	/// The local anchor point relative to bodyA's origin.
	public b2Vec2 GetLocalAnchorA() {
		return new b2Vec2(jniGetLocalAnchorA(address));
	}

	/// The local anchor point relative to bodyB's origin.
	public b2Vec2 GetLocalAnchorB() {
		return new b2Vec2(jniGetLocalAnchorB(address));
	}

	/// Set/Get the maximum length of the rope.
	public void SetMaxLength(float length) {
		jniSetMaxLength(address, length);
	}

	public float GetMaxLength() {
		return jniGetMaxLength(address);
	}

	public b2LimitState GetLimitState() {
		b2LimitState[] states = b2LimitState.values();
		int index = jniGetLimitState(address);
		return states[index];
	}

	/// Dump to b2Log.
	public void Dump() {
		throw new UnsupportedOperationException();
	}

	private static native int jniGetAnchorA(int me);
	private static native int jniGetAnchorB(int me);
	private static native float jniGetReactionTorque(int me, float inv_dt);
	private static native int jniGetReactionForce(int me);
	private static native int jniGetLocalAnchorA(int me);
	private static native int jniGetLocalAnchorB(int me);
	private static native void jniSetMaxLength(int me, float length);
	private static native float jniGetMaxLength(int me);
	private static native int jniGetLimitState(int me);
}
